//
//  CBuffer.cpp
//  OpenGLDemo
//
//  Created by 石超军 on 2018/7/6.
//  Copyright © 2018年 石超军. All rights reserved.
//
#include <OpenGL/gl3.h>
#include "CVertex.h"
#include <cmath>
#include <fstream>

const unsigned int CVertex::FVF_POS = 1;
const unsigned int CVertex::FVF_COLOR = 2;
const unsigned int CVertex::FVF_NORMAL = 4;
const unsigned int CVertex::FVF_TEX2D = 8;

const unsigned int CVertex::FVF_BIT[] ={3,3,3,2};

CVertex::CVertex(unsigned int vFormat,CVERTEX_INFO* info,const float vertices[] ,unsigned int verticesLen,
                 const unsigned int indices[],unsigned int indicesLen)
{
    LoadFromParams(vFormat,info,vertices,verticesLen,indices,indicesLen);
}
CVertex::CVertex(std::function<void(unsigned int,unsigned int,unsigned int)> lam)
{
   
    glGenBuffers(1, &m_VBO);
    glGenBuffers(1, &m_EBO);
    glGenVertexArrays(1, &m_VAO);
    
    ///绑定设置到VAO中,绑定VBO到缓存数组中
    glBindVertexArray(m_VAO);    //绑定设置到VAO-接下来的设置都会保存到VAO中
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);//绑定VBO对象到GL_ARRAY_BUFFER-任何（在GL_ARRAY_BUFFER目标上的）缓冲调用都会用来配置当前绑定的缓冲
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
    
    lam(m_VAO,m_VBO,m_EBO);
}

CVertex::CVertex(std::string path)
{
    LoadFromFile(path.c_str());
}

CVertex::CVertex(const CVERTEX_DATA *info)
{
    LoadFromParams(info->format,nullptr,info->vertices.data,info->vertices.len,info->indices.data,info->indices.len);
}

CVertex::~CVertex()
{
    glDeleteVertexArrays(1, &m_VAO);
    glDeleteBuffers(1, &m_VBO);
    glDeleteBuffers(1, &m_EBO);
}

bool CVertex::LoadFromParams(unsigned int vFormat,CVERTEX_INFO* info,const float vertices[],unsigned int verticesLen,
                    const unsigned int indices[],unsigned int indicesLen)
{
    glGenVertexArrays(1, &m_VAO);
    glGenBuffers(1, &m_VBO);
    glGenBuffers(1, &m_EBO);
    
    ///绑定设置到VAO中
    glBindVertexArray(m_VAO);    //绑定设置到VAO-接下来的设置都会保存到VAO中

    
    unsigned int curPos = 0;
    unsigned int curSize = 0;
    unsigned int totalCount = 0;
    unsigned int totalSize = 0;
    int i=0;
    int count = sizeof(FVF_BIT)/sizeof(int);
    {
        if(vertices)
        {
            glBindBuffer(GL_ARRAY_BUFFER, m_VBO);//绑定VBO对象到GL_ARRAY_BUFFER-任何（在GL_ARRAY_BUFFER目标上的）缓冲调用都会用来配置当前绑定的缓冲
            glBufferData(GL_ARRAY_BUFFER, verticesLen, vertices, GL_STATIC_DRAW);//将顶点数据写入绑定的顶点缓存对象
        }
        if(indices)
        {
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesLen, indices, GL_STATIC_DRAW);
        }
        
        for(i=0;i<count;++i)
        {
            int pos = pow(2,i);
            if((vFormat & pos) != 0)
            {
                totalSize+=FVF_BIT[i];
                ++totalCount;
            }
        }
        for(i=0;i<count;++i)
        {
            int pos = pow(2,i);
            if((vFormat & pos) != 0)
            {
                glVertexAttribPointer(curPos, FVF_BIT[i], GL_FLOAT, GL_FALSE, totalSize * sizeof(float), (void*)(curSize * sizeof(float)));
                glEnableVertexAttribArray(curPos);
                curSize+=FVF_BIT[i];
                ++curPos;
            }
        }
    }
    if(info)
    {
        if(vertices)
            info->patches = verticesLen/totalSize;
        else
            info->patches = 0;
        if(indices)
            info->elements = indicesLen/sizeof(int);
        else
            info->elements = 0;
    }
    
    return true;
}

bool CVertex::LoadFromFile(const char* file)
{
    CVertex::~CVertex();
    
    glGenBuffers(1, &m_VBO);
    glGenBuffers(1, &m_EBO);
    glGenVertexArrays(1, &m_VAO);
    
    ///绑定设置到VAO中,绑定VBO到缓存数组中
    glBindVertexArray(m_VAO);    //绑定设置到VAO-接下来的设置都会保存到VAO中
    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);//绑定VBO对象到GL_ARRAY_BUFFER-任何（在GL_ARRAY_BUFFER目标上的）缓冲调用都会用来配置当前绑定的缓冲
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
    
    //用于存储顶点数据
    float *vertice = nullptr;
    unsigned int *indices = nullptr;
    //内容提取
    {
        std::ifstream in;
        in.open(file,std::ios::in);
        if(in.is_open())
        {

            static const char* KEY_VERTEX_NODE = "vertries:";
            static const char* KEY_INDEX_NODE = "indices:";
            
            static const char* KEY_VERTEX_COUNT = "count:";
            static const char* KEY_VERTEX_HEAD = "head:";
            static const char* KEY_VERTEX_DATA = "data:";
            
            static const char* KEY_INDEX_COUNT = "count:";
            static const char* KEY_INDEX_HEAD = "head:";
            static const char* KEY_INDEX_DATA = "data:";
            
            static const char* KEY_ANNOTATION = "//";
            
            
            static const int STATE_ANNOTATION = -1;          //注释状态
            static const int STATE_VERTEX = 1;               //顶点解析
            
            //每行读入1024个字节
            char buf[1024];
            int state = 0;  //状态机
            while(in.getline(buf, 1024))
            {


                char *pos = 0;
                {
                    //查找
                    if((pos = strstr(buf,KEY_VERTEX_NODE)) != NULL)
                    {
                        

                    }
                }
            }
            in.close();
            return true;
        }else{
            
            in.close();
            return false;
        }

    }
    
    return false;
}

void CVertex::Bind()
{
    glBindVertexArray(m_VAO);             //激活顶点数组对象
}

void CVertex::Draw()
{
    
}
